#include "frame_thread_pool.h"

#include "users_login.h"
#include "deal_command.h"  // 包含 struct_userOpInfo struct_tlv

static void *threadFunc(void *arg) {
    threadPool_t *threadPool = (threadPool_t *)arg;

    while(1) {
        int netfd;

        pthread_mutex_lock(&threadPool->mutex);

        while(threadPool->taskQueue.size == 0 && threadPool->exitFlag == 0) {
            pthread_cond_wait(&threadPool->cond, &threadPool->mutex);
        }

        if(threadPool->exitFlag == 1) {
            printf("\nI am worker. I am going to exit!\n");
            // 子线程退出不用dequeue， 不用关netfd， 主线程帮着关了
            pthread_mutex_unlock(&threadPool->mutex);
            pthread_exit(NULL);
        }

        deQueue(&threadPool->taskQueue, &netfd);
        printf("\nI am worker, I got netfd = %d\n", netfd);

        pthread_mutex_unlock(&threadPool->mutex);

        printf("Next, do something!\n");
        printf("\n");


        // work

        // 登录 注册功能
        userOpInfo_t useropinfo;
        memset(&useropinfo, 0, sizeof(useropinfo));

        // 初始化useropinfo  mysql netfd addr 
        // ID uesrName 在Login得到
        // opName 在recv得到
        useropinfo.mysql = threadPool->mysql;
        useropinfo.netfd = netfd;
        strcpy(useropinfo.addr, userSpace);

        int ret = 1;
        ret = usersLogin(&useropinfo);
        if(ret == -1) {
            printf("\n");
            pthread_exit(NULL);
        }

        printf("In thread: netfd = %d\n", useropinfo.netfd);
        printf("In thread: ID = %d\n", useropinfo.ID);
        printf("In thread: addr = %s\n", useropinfo.addr);
        printf("In thread: userName = %s\n", useropinfo.userName);
        printf("\n");

        // 处理客户端请求
        // 对每一个客户端输入的命令
        // 收客户端发来的命令
        // 然后根据命令tlv的t执行相应的操作
        // 最后将操作的结果返回给客户端
        tlvPacket_t tlv;
        memset(&tlv, 0, sizeof(tlv));

        while(1) {
            ret = recv(useropinfo.netfd, &tlv.type, sizeof(tlv.type), MSG_WAITALL);
            if(ret == 0) {
                break;
            }
            ret = recv(useropinfo.netfd, &tlv.length, sizeof(tlv.length), MSG_WAITALL);
            if(ret == 0) {
                break;
            }
            if(tlv.length != 0) {
                ret = recv(useropinfo.netfd, tlv.value, tlv.length, MSG_WAITALL);
                if(ret == 0) {
                    break;
                }              
                memset(useropinfo.opName, 0, sizeof(useropinfo.opName));
                strncpy(useropinfo.opName, tlv.value, sizeof(useropinfo.opName));
                useropinfo.opName[tlv.length] = '\0';
            }

            printf("command: %d,  file: %s\n", tlv.type, useropinfo.opName);

            ret = dealCommand(&useropinfo, &tlv);  
            if(ret == -1) {
                printf("Error! waiting for next command\n\n");
                continue;
            }
            printf("\n");
        }

        close(netfd);

    }
}

int makeWorker(threadPool_t *threadPool) {
    for(int i = 0; i < threadPool->tidArr.workerNum; i++) {
        pthread_create(&threadPool->tidArr.arr[i], NULL, threadFunc, threadPool);
    }
    return 0;
}
